#region Header

// MS codename Velocity Distributed Cache Extensions.
// (c) 2009

#endregion


#region Usings

using System;
using System.Diagnostics;

using Caching.Extensions.Core.Impl;

#endregion


namespace Caching.Extensions.Core.Setup
{
    /// <summary>
    /// class to configure <see cref="SmartCache"/> instrumentation.
    /// </summary>
    public class SmartCacheInstrumentationConfigurator
    {
        /// <summary>
        /// Creates the remote cache category.
        /// </summary>
        public void CreateRemoteCacheCategory()
        {
        }


        /// <summary>
        /// Creates the local cache category.
        /// </summary>
        /// <param name="recreate">if set to <c>true</c> [recreate].</param>
        /// <returns></returns>
        public bool CreateLocalCacheCategory(bool recreate)
        {
            if (recreate)
                RemoveLocalCacheCategory();

            bool localCacheAlreadyExists = PerformanceCounterCategory.Exists(LocalCachePerfCounters.CategoryName);
            if (!localCacheAlreadyExists)
            {
                PerformanceCounterCategory category = PerformanceCounterCategory.Create(
                    LocalCachePerfCounters.CategoryName,
                    "SmartCache: Local cache performance counters",
                    PerformanceCounterCategoryType.SingleInstance,
                    BuildLocalCacheCounters()
                    );
            }

            return !localCacheAlreadyExists;
        }


        /// <summary>
        /// Creates the remote cache category.
        /// </summary>
        /// <param name="recreate">if set to <c>true</c> [recreate].</param>
        /// <returns></returns>
        public bool CreateRemoteCacheCategory(bool recreate)
        {
            if (recreate)
                RemoveRemoteCacheCategory();
            bool categoryExists = PerformanceCounterCategory.Exists(RemoteCachePerfCounters.CategoryName);
            if (!categoryExists)
            {
                PerformanceCounterCategory.Create(
                    RemoteCachePerfCounters.CategoryName, "SmartCache: Remote cache performance counters",
                    PerformanceCounterCategoryType.MultiInstance,
                    BuildRemoteCacheCounters()
                    );
            }
            return categoryExists;
        }


        /// <summary>
        /// Removes the remote cache category.
        /// </summary>
        public void RemoveRemoteCacheCategory()
        {
            if (PerformanceCounterCategory.Exists(RemoteCachePerfCounters.CategoryName))
                PerformanceCounterCategory.Delete(RemoteCachePerfCounters.CategoryName);
        }


        /// <summary>
        /// Removes the local cache category.
        /// </summary>
        public void RemoveLocalCacheCategory()
        {
            if (PerformanceCounterCategory.Exists(LocalCachePerfCounters.CategoryName))
                PerformanceCounterCategory.Delete(LocalCachePerfCounters.CategoryName);
        }


        internal CounterCreationDataCollection BuildLocalCacheCounters()
        {
            var collection = new CounterCreationDataCollection
                {
                    new CounterCreationData(LocalCachePerfCounters.HitsPerInterval, "Local cache hits/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(LocalCachePerfCounters.HitsTotal, "Total # of local cache hits",
                        PerformanceCounterType.NumberOfItems32),
                    new CounterCreationData(LocalCachePerfCounters.MissesPerInterval, "Local cache misses/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(LocalCachePerfCounters.MissesTotal, "Total # local cache misses",
                        PerformanceCounterType.NumberOfItems32),
                    new CounterCreationData(LocalCachePerfCounters.PutsPerInterval, "Local cache puts/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(LocalCachePerfCounters.RemovesPerInterval, "Local cache removes/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(LocalCachePerfCounters.CleanupsTotal, "Total # of local cache cleanups",
                        PerformanceCounterType.NumberOfItems32),
                    new CounterCreationData(LocalCachePerfCounters.ErrorsTotal, "Total # of local cache errors",
                        PerformanceCounterType.NumberOfItems32),
                    new CounterCreationData(LocalCachePerfCounters.ErrorsPerSecond, "# of local cache error/second",
                        PerformanceCounterType.RateOfCountsPerSecond32)
                };
            return collection;
        }


        internal CounterCreationDataCollection BuildRemoteCacheCounters()
        {
            var collection = new CounterCreationDataCollection
                {
                    new CounterCreationData(RemoteCachePerfCounters.HitsPerSecond, "Hits/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(RemoteCachePerfCounters.HitsTotal, "Total # of hits",
                        PerformanceCounterType.NumberOfItems32),
                    new CounterCreationData(RemoteCachePerfCounters.MissesPerSecond, "Misses/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(RemoteCachePerfCounters.MissesTotal, "Total # of misses",
                        PerformanceCounterType.NumberOfItems32),
                    new CounterCreationData(RemoteCachePerfCounters.QueryUpdateHitsPerSecond, "QueryUpdate hits/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(RemoteCachePerfCounters.QueryUpdateMissesPerSecond, "QueryUpdate/seconds",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(RemoteCachePerfCounters.ErrorsPerSecond, "Errors/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(RemoteCachePerfCounters.ErrorsTotal, "Total # of errors",
                        PerformanceCounterType.NumberOfItems32),
                    new CounterCreationData(RemoteCachePerfCounters.RegionOperationsTotal,
                        "Total # of region operations",
                        PerformanceCounterType.NumberOfItems32),
                    new CounterCreationData(RemoteCachePerfCounters.RemovesPerSecond, "Removes/second",
                        PerformanceCounterType.RateOfCountsPerSecond32),
                    new CounterCreationData(RemoteCachePerfCounters.PutsPerSecond, "# of puts/second",
                        PerformanceCounterType.RateOfCountsPerSecond32)
                };
            return collection;
        }
    }
}